package common

import "sync"

var goGlobalMap sync.Map

func set(key, v interface{}) {
	goGlobalMap.Store(key, v)
}

func get(key interface{}) interface{} {
	if v, ok := goGlobalMap.Load(key); ok {
		return v
	}
	return nil
}

func del(k interface{}) {
	goGlobalMap.Delete(k)
}

func getLocalLocks(goId uint64) map[string]uint64 {
	value := get(goId)
	if value == nil {
		return make(map[string]uint64, 0)
	} else {
		return value.(map[string]uint64)
	}
}

func setLocalLocks(goId uint64, v map[string]uint64) {
	if v == nil || len(v) == 0 {
		// 清空列表
		del(goId)
	} else {
		// 设置列表
		set(goId, v)
	}
}

func Lock(ids ...string) {
	goId := SelfRuntime.GoId()
	localLocks := getLocalLocks(goId)
	for _, id := range ids {
		if _, ok := localLocks[id]; !ok {
			RedisLock(id, goId)
			localLocks[id] = goId
		}
	}
	setLocalLocks(goId, localLocks)
}

func GetLock(ids ...string) bool {
	goId := SelfRuntime.GoId()
	localLocks := getLocalLocks(goId)
	for _, id := range ids {
		if _, ok := localLocks[id]; !ok {
			flag := RedisGetLock(id, goId)
			if !flag {
				return flag
			}
			localLocks[id] = goId
		}
	}
	setLocalLocks(goId, localLocks)
	return true
}

func Unlock(ids ...string) {
	goId := SelfRuntime.GoId()
	localLocks := getLocalLocks(goId)
	for _, id := range ids {
		if _, ok := localLocks[id]; ok {
			RedisUnlock(id, goId)
		}
	}
	for _, id := range ids {
		delete(localLocks, id)
	}
	setLocalLocks(goId, localLocks)
}

func UnlockAll() {
	goId := SelfRuntime.GoId()
	localLocks := getLocalLocks(goId)
	for id, _ := range localLocks {
		RedisUnlock(id, goId)
	}
	setLocalLocks(goId, nil)
}
